#!/bin/bash
# -------------------------------------------------------------------------
# The New Linux Counter Project
# Copyright (c) 2011 LinuxCounter project
# This script is licensed under GNU GPL version 2.0 or above
# For more info, please visit:
#            http://linuxcounter.net
# -------------------------------------------------------------------------

scriptversion="lico-update.sh version 0.3.4"

export LANG=C

PATH="~/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
SPATH=$( pwd 2>/dev/null )
SHADOW_FILE="/etc/shadow"
PASSWD_FILE="/etc/passwd"
LSB_FILE="/etc/lsb-release"

# Bins
DF=$( which df 2>/dev/null )
DATE=$( which date 2>/dev/null )
HOSTNAME=$( which hostname 2>/dev/null )
CAT=$( which cat 2>/dev/null )
PS=$( which ps 2>/dev/null )
AWK=$( which awk 2>/dev/null )
GREP=$( which grep 2>/dev/null )
EGREP=$( which egrep 2>/dev/null )
LASTLOG=$( which lastlog 2>/dev/null )
ID=$( which id 2>/dev/null )
UNAME=$( which uname 2>/dev/null )
BASENAME=$( which basename 2>/dev/null )
LAST=$( which last 2>/dev/null )
LASTLOGIN=$( which lastlogin 2>/dev/null )
FIND=$( which find 2>/dev/null )
UPTIME=$( which uptime 2>/dev/null )
HEAD=$( which head 2>/dev/null )
TAIL=$( which tail 2>/dev/null )
CUT=$( which cut 2>/dev/null )
W=$( which w 2>/dev/null )
WC=$( which wc 2>/dev/null )
SED=$( which sed 2>/dev/null )
NETSTAT=$( which netstat 2>/dev/null )
RUNLEVEL=$( which runlevel 2>/dev/null )
IFCONFIG=$( which ifconfig 2>/dev/null )
DMESG=$( which dmesg 2>/dev/null )
KLDSTAT=$( which kldstat 2>/dev/null )
SYSCTL=$( which sysctl 2>/dev/null )
LSMOD=$( which lsmod 2>/dev/null )
IOSTAT=$( which iostat 2>/dev/null )
MD5SUM=$( which md5sum 2>/dev/null )
CURL=$( which curl 2>/dev/null )
WGET=$( which wget 2>/dev/null )
LINKS=$( which links 2>/dev/null )
PERL=$( which perl 2>/dev/null )
PYTHON=$( which python 2>/dev/null )
PHP=$( which php 2>/dev/null )
AT=$( which at 2>/dev/null )
CRONTAB=$( which crontab 2>/dev/null )
FILE=$( which file 2>/dev/null )
SORT=$( which sort 2>/dev/null )
LSB_RELEASE=$( which lsb_release 2>/dev/null ) 

SCRIPTNAME=$( basename ${0} )
SCRIPT=$( readlink -f "${0}" )


if [ "${UNAME}" == "" ]; then
  echo "> Program \"uname\" is needed to run this script!"
  exit 1
fi

OS=$( $UNAME )
if [ "$OS" != "Linux" ]; then
  echo "This script actually supports only Linux!"
  exit 1
fi

if [ ! -r "${LSB_FILE}" -a "${LSB_RELEASE}" == "" ]; then
  echo "> Program \"lsb_release\" is needed to run this script!"
  echo "  If this program is not available in your distribution repositories, then"
  echo "  Please create the file \"${LSB_FILE}\" with the following content:"
  echo "DISTRIB_ID=\"Your Distribution Name\""
  echo "DISTRIB_RELEASE=\"The version string of your distribution\""
  exit 1
fi
if [ "${GREP}" == "" ]; then
  echo "> Program \"grep\" is needed to run this script!"
  exit 1
fi
if [ "${CAT}" == "" ]; then
  echo "> Program \"cat\" is needed to run this script!"
  exit 1
fi
if [ "${HEAD}" == "" ]; then
  echo "> Program \"head\" is needed to run this script!"
  exit 1
fi
if [ "${TAIL}" == "" ]; then
  echo "> Program \"tail\" is needed to run this script!"
  exit 1
fi
if [ "${AWK}" == "" ]; then
  echo "> Program \"awk\" is needed to run this script!"
  exit 1
fi
if [ "${SED}" == "" -a "${OS}" == "Linux" ]; then
  echo "> Program \"sed\" is needed to run this script!"
  exit 1
fi
if [ "${WGET}" == "" -a "${CURL}" == "" ]; then
  echo "> Either curl or wget is needed to run this script!"
  exit 1
fi
if [ "${PYTHON}" == "" -a "${PERL}" == "" -a "${PHP}" == "" ]; then
  echo "> Either python, perl or php is needed to run this script!"
  exit 1
fi


if [ "$($ID -u)" == "0" ]; then
  echo "DO NOT RUN THIS SCRIPT WITH USER \"root\"!!!"
  exit 1
fi


if [ -z "${1}" ]; then
  echo " Usage:  ${SCRIPTNAME} -i|-s|-m|-ci|-cu|-h|-v"
  echo " Use -h to get more help."
  exit 1
fi


if [ "${LSB_RELEASE}" == "" ]; then  
  if [ -r ${LSB_FILE} ]; then 
    . ${LSB_FILE} 
    distribution="${DISTRIB_ID}" 
    distribversion="${DISTRIB_RELEASE}" 
  else 
    distribution="" 
    distribversion="" 
  fi 
else
  distribution=$($LSB_RELEASE -is) 
  distribversion=$($LSB_RELEASE -rs) 
fi

# Displays OS name for example FreeBSD, Linux etc
getOs(){
  echo "$($UNAME)"
}

# Display hostname
# host (FQDN hostname), for example, vivek (vivek.text.com)
getHostName(){
  [ "$OS" == "Linux" ] && echo "$($HOSTNAME)" || :
}

# Display CPU information such as Make, speed
getAccounts(){
  [ "$OS" == "Linux" ] && echo $($CAT ${PASSWD_FILE} 2>/dev/null | ${AWK} -F':' '{ if($3 >= 1000) print $0 }' | $WC -l) || :
}

# Get CPU model name
getCpuInfo(){
  [ "$OS" == "Linux" ] && echo $($GREP -i "model name" /proc/cpuinfo | $HEAD -n 1 | $SED "s/.*: \(.*\)/\1/") || :
}

# Get CPU MHz
getCpuFreq(){
  [ "$OS" == "Linux" ] && echo $($GREP -i "cpu mhz" /proc/cpuinfo | $HEAD -n 1 | $SED "s/.*: \(.*\)/\1/") || :
}

# get CPU flags
getCpuFlags(){
  [ "$OS" == "Linux" ] && echo $($GREP -i "flags" /proc/cpuinfo | $HEAD -n 1 | $SED "s/.*: \(.*\)/\1/") || :
}

# get CPU Cores
getNumCPUCores(){
  [ "$OS" == "Linux" ] && echo $($GREP -i "model name" /proc/cpuinfo | $WC -l) || :
}

# Display total RAM in system
getTotalRam(){
  [ "$OS" == "Linux" ] && echo $($GREP -i "memtotal" /proc/meminfo | $HEAD -n 1 | $SED "s/.*: *\(.*\) kB/\1/") || :
}

# Display free RAM in system
getFreeRam(){
  [ "$OS" == "Linux" ] && echo $($GREP -i "memfree" /proc/meminfo | $HEAD -n 1 | $SED "s/.*: *\(.*\) kB/\1/") || :
}

# Display total Swap in system
getTotalSwap(){
  [ "$OS" == "Linux" ] && echo $($GREP -i "swaptotal" /proc/meminfo | $HEAD -n 1 | $SED "s/.*: *\(.*\) kB/\1/") || :
}

# Display free Swap in system
getFreeSwap(){
  [ "$OS" == "Linux" ] && echo $($GREP -i "swapfree" /proc/meminfo | $HEAD -n 1 | $SED "s/.*: *\(.*\) kB/\1/") || :
}

# Display system load for last 5,10,15 minutes
getSystemLoad(){
  [ "$OS" == "Linux" ] && echo "$($UPTIME | $AWK -F'load average:' '{ print $2 }')" || :
}

# List total number of users logged in (both Linux and FreeBSD)
getNumberOfLoggedInUsers(){
  [ "$OS" == "Linux" ] && echo "$($W -h | ${CUT} -d " " -f 1 | ${SORT} -u | $WC -l)" || :
}

getTotalDiskSpace() {
  [ "$OS" == "Linux" ] && echo $(${DF} -P | ${EGREP} "^/dev/" | ${SED} "s/  */\ /g" | ${CUT} -d " " -f 2 | ${AWK} '{s+=$1} END {print s}') || :
}

getFreeDiskSpace() {
  [ "$OS" == "Linux" ] && echo $(${DF} -P | ${EGREP} "^/dev/" | ${SED} "s/  */\ /g" | ${CUT} -d " " -f 4 | ${AWK} '{s+=$1} END {print s}') || :
}

getUptime() {
  [ "$OS" == "Linux" ] && echo $($UPTIME | ${SED} "s/.* up \([^,]*\), .*/\1/g") || :
}


if [ "${1}" == "-h" ]; then
  echo ""
  echo "# -------------------------------------------------------------------- #"
  echo "#                        LiCo - The New Linux Counter Project          #"
  echo "# Copyright (c) 2011 LiCo - The New Linux Counter Project              #"
  echo "# This script is licensed under GNU GPL version 2.0 or above           #"
  echo "# For more info, please visit: http://linuxcounter.net                 #"
  echo "# -------------------------------------------------------------------- #"
  echo ""
  echo " Usage:  ${SCRIPTNAME} -i|-s|-m|-ci|-cu|-h|-v"
  echo ""
  echo "   -i       Use this switch to enter interactive mode. The script will"
  echo "            then ask you a few questions related your counter"
  echo "            membership. Your entered data will be stored in"
  echo "            ~/.linuxcounter/<hostname>"
  echo ""
  echo "   -s       This will show you what will be sent to the counter, without"
  echo "            sending anything. The script will only send with -m."
  echo ""
  echo "   -m       Use this switch to let the script send the collected data"
  echo "            to the counter project. If the machine entry does not exist,"
  echo "            it will be created."
  echo ""
  echo "   -ci      Use this switch to automatically create a cronjob (or at job)"
  echo "             for this script. The data will then get sent once per week."
  echo ""
  echo "   -cu      Use this to uninstall the cronjob (or at job)"
  echo ""
  echo "   -h       Well, you've just used that switch, no?"
  echo "   -v       This gives you the version of this script"
  echo ""
  echo " ATTENTION:"
  echo " You NEED to rerun \"lico-update.sh -i\" and enter your number and the"
  echo " number of the machine it has to update. Otherwise, the script would"
  echo " create a new machine on each run!"
  echo ""
  echo ""
  echo " More information here:  http://linuxcounter.net/script.html"
  echo ""
  exit 0
fi
if [ "${1}" == "-v" ]; then
  echo ""
  echo "# -------------------------------------------------------------------- #"
  echo "#                        LiCo - The New Linux Counter Project          #"
  echo "# Copyright (c) 2011 LiCo - The New Linux Counter Project              #"
  echo "# This script is licensed under GNU GPL version 2.0 or above           #"
  echo "# For more info, please visit: http://linuxcounter.net                 #"
  echo "# -------------------------------------------------------------------- #"
  echo ""
  echo " ${scriptversion}"
  echo ""
  exit 0
fi
if [ "${1}" == "-ci" ]; then
  ${CRONTAB} -l > /tmp/crontab.tmp
  isset=$( ${GREP} "lico-update" /tmp/crontab.tmp )
  if [ "${isset}" != "" ]; then
    echo "The cronjob already is active!"
    exit 1
  else
    min=$(($RANDOM%60+0))
    hour=$(($RANDOM%12+8))
    dow=$(($RANDOM%7+0))
    echo "${min} ${hour} * * ${dow} ${SCRIPT} -m" >> /tmp/crontab.tmp
    ${CRONTAB} /tmp/crontab.tmp
    rm /tmp/crontab.tmp
    echo "The cronjob was successfully activated!"
    exit 0
  fi
fi
if [ "${1}" == "-cu" ]; then
  ${CRONTAB} -l > /tmp/crontab.tmp
  isset=$( ${GREP} "lico-update" /tmp/crontab.tmp )
  if [ "${isset}" == "" ]; then
    echo "The cronjob is not active!"
    exit 1
  else
    ${SED} '/lico-update/d' -i /tmp/crontab.tmp
    ${CRONTAB} /tmp/crontab.tmp
    rm /tmp/crontab.tmp
    echo "The cronjob was successfully removed!"
    exit 0
  fi
fi

script=${scriptversion}
hostname=$(getHostName)
version=$($UNAME -r)
machine=$($UNAME -m)
processor=$(getCpuInfo)
cpunum=$(getNumCPUCores)
flags=$(getCpuFlags)
totalram=$(getTotalRam)
freeram=$(getFreeRam)
totalswap=$(getTotalSwap)
freeswap=$(getFreeSwap)
load=$(getSystemLoad)
date=$($DATE)
numusers=$(getNumberOfLoggedInUsers)
accounts=$(getAccounts)
totaldisk=$(getTotalDiskSpace)
freedisk=$(getFreeDiskSpace)
uptime=$(getUptime)
cpufreq=$(getCpuFreq)

if [ -r ~/.linuxcounter/${hostname} ]; then
  if [ $( ${FILE} ~/.linuxcounter/${hostname} | ${CUT} -d " " -f 2) == "ASCII" ]; then
    rm ~/.linuxcounter/${hostname}
    if [ "${1}" != "-i" ]; then
      echo "Host information file in wrong (old) format!"
      echo "Please run \"${SCRIPTNAME} -i\" first."
      exit 1
    fi
  else
    . ~/.linuxcounter/${hostname}
  fi
else
  if [ "${1}" != "-i" ]; then
    echo "Host information file not found!"
    echo "Please run \"${SCRIPTNAME} -i\" first."
    exit 1
  fi
fi

string="${script}##${hostname}##${counter_number}##${machine_number}##${processor}##${cpunum}##${accounts}##${totaldisk}##${totalram}##${numusers}##${freedisk}##${freeram}##${totalswap}##${freeswap}##${flags}##${machine}##${version}##${uptime}##${load}##${cpufreq}##${distribution}##${distribversion}"
if [ "${1}" == "-m" ]; then
  if [ "${machine_number}" == "" ]; then
    echo "ATTENTION: You have still not entered a machine number!"
    echo "Please run \"lico-update.sh -i\" and enter your counter number and the"
    echo "number for the machine this script has to update. Otherwise this script"
    echo "will create a new machine on each run!"
    echo ""
    echo "Continue anyway? [N/y]"
    read confirm
    if [ "${confirm}" == "" ]; then
      exit 1
    elif [ "${confirm}" == "y" -o "${confirm}" == "Y" ]; then
      true
    elif [ "${confirm}" == "n" -o "${confirm}" == "N" ]; then
      exit 1
    else    
      exit 1
    fi
  fi
  date=$( date +%Y%m%d%H%M%S )
  tmpfile="/tmp/lico-update.${counter_number}.${date}.tmp"
  if [ "${PYTHON}" != "" ]; then
    sendstring=$( ${PYTHON} -c "import sys, urllib as ul; print ul.quote_plus(\"${string}\")" )
  elif [ "${PERL}" != "" ]; then
    sendstring=$( ${PERL} -MURI::Escape -e 'print uri_escape($ARGV[0]);' "${string}" )
  elif [ "${PHP}" != "" ]; then
    sendstring=$( ${PHP} -r "echo urlencode(\"${string}\");"; )
  fi
  if [ "${WGET}" != "" ]; then
    ${WGET} -q -O ${tmpfile}  --no-check-certificate --post-data "senddata=${sendstring}" https://linuxcounter.net/api.php >/dev/null 2>&1
    output=$( ${CAT} ${tmpfile} )
    rm ${tmpfile}
    if [ "${output}" != "" ]; then
      echo ${output}
      exit 1
    else
      exit 0
    fi
  else
    echo "Program wget not found! Actually only wget is supported to send the data!"
    exit 1
  fi
fi

if [ "${1}" == "-i" ]; then
  echo "> entering interactive mode..."
  echo ""
  echo "In order to assign the data sent by this script to the correct user"
  echo "account, I will need your counter user number."
  echo "Please enter your counter number:"
  echo -n " [${counter_number}]  "
  read counter_numbern
  if [ "${counter_numbern}" != "" ]; then
    counter_number=${counter_numbern}
  fi
  echo ""
  echo ""
  echo "If this machine already exists in your counter profile, then"
  echo "I will also need the machine counter number in order to assign"
  echo "the data to the correct machine."
  echo "Please enter the machine number (if any):  "
  echo -n " [${machine_number}]  "
  read machine_numbern
  if [ "${machine_numbern}" != "" ]; then
    machine_number=${machine_numbern}
  fi
  echo ""
  echo ""
  if [ "${distribution}" == "" ]; then
    echo "I was not able to detect your distribution on this machine."
    echo "Please enter the name of the distribution (without version!):  "
    echo -n " [${distribution}]  "
    read distributionn
    if [ "${distributionn}" != "" ]; then
      distribution=${distributionn}
    fi
    echo ""
    echo ""
  fi
  if [ "${distribversion}" == "" ]; then
    echo "I was not able to detect the version of your distribution."
    echo "Please enter only the version information of this distribution:  "
    echo " [${distribversion}]  "
    read distribversionn
    if [ "${distribversionn}" != "" ]; then
      distribversion=${distribversionn}
    fi
    echo ""
    echo ""
  fi
  if [ ! -d ~/.linuxcounter ]; then
    mkdir ~/.linuxcounter
    chmod 700 ~/.linuxcounter
  fi
  echo "#!/bin/bash" > ~/.linuxcounter/${hostname}
  echo "scriptversion=\"${scriptversion}\"" >> ~/.linuxcounter/${hostname}
  echo "hostname=\"${hostname}\"" >> ~/.linuxcounter/${hostname}
  echo "counter_number=\"${counter_number}\"" >> ~/.linuxcounter/${hostname}
  echo "machine_number=\"${machine_number}\"" >> ~/.linuxcounter/${hostname}
  echo "distribution=\"${distribution}\"" >> ~/.linuxcounter/${hostname}
  echo "distribversion=\"${distribversion}\"" >> ~/.linuxcounter/${hostname}
  chmod 700 ~/.linuxcounter/${hostname}
  echo "Host file created: ~/.linuxcounter/${hostname}"
  echo "Thanks!"
  exit 0
fi

if [ "${1}" == "-s" ]; then
  echo " The following data will be sent to the counter:"
  echo ""
  echo " ================================================================"
  echo " Script:          ${script}"
  echo " Hostname:        ${hostname}"
  echo " Distribution:    ${distribution}"
  echo " Distrib Version: ${distribversion}"
  echo " Counter Num:     ${counter_number}"
  echo " Machine Num:     ${machine_number}"
  echo " Processor:       ${processor}"
  echo " CPU Frequency:   ${cpufreq}"
  echo " CPU flags:       ${flags}"
  echo " Num cores:       ${cpunum}"
  echo " Num of Accounts: ${accounts}"
  echo " Num of users:    ${numusers}"
  echo " Total diskspace: ${totaldisk}"
  echo " Free diskspace:  ${freedisk}"
  echo " Total RAM:       ${totalram}"
  echo " Free RAM:        ${freeram}"
  echo " Total Swap:      ${totalswap}"
  echo " Free Swap:       ${freeswap}"
  echo " Architecture:    ${machine}"
  echo " Kernel:          ${version}"
  echo " Uptime:          ${uptime}"
  echo " Load:            ${load}"
  echo ""
  echo " The exact string the script sends to the counter database is this:"
  echo ""
  echo " ${string}"
  echo ""
  echo " The string consists of all information mentioned above separated by \"##\"."
  echo " ================================================================"
  echo ""
  echo " Actually nothing was sent to the counter! Use -m to send the data."
  exit 0
fi















exit 0
# end